// 独立监听某个数据的变化
// 提供一个可以执行函数的场所
class Watcher {
    constructor(opts) {
      this.$data = this.getBaseType(opts.data) === 'Object' ? opts.data : {}
      this.$watch = this.getBaseType(opts.watch) === 'Object' ? opts.watch : {}
      for (let key in opts.data) {
        this.setData(key) // a, b
      }
    }
  
    getBaseType(target) {
      let typeStr = Object.prototype.toString.call(target)
      return typeStr.slice(8, -1)
    }
  
    // {
    //   $data: {
    //     a: 0,
    //     b: 1
    //   }
    // }
    setData(_key) {
      Object.defineProperty(this, _key, { // Object.defineProperty(this) 会把上下文指向当前的对象, 往外多劫持了一层
        get: function() {
          return this.$data[_key]
        },
        set: function(newVal) {
          // console.log(newVal);
          const oldVal = this.$data[_key] // 0
          if (newVal === oldVal) return newVal
          this.$data[_key] = newVal // 1
          // 调用$watch里面的函数
          this.$watch[_key] && this.getBaseType(this.$watch[_key]) === 'Function' && (
            this.$watch[_key].call(this, newVal, oldVal)
          )
        }
      })
    }
  }
  
  
  let vm = new Watcher({
    data: {
      a: 0,
      b: 'hello'
    },
    watch: {
      a: function(newVal, oldval) {
        console.log(newVal, oldval);
      }
    }
  }) 
  
  setTimeout(() => {
    vm.a = 1
  }, 1000)
  